package dao

import (
	"context"
	"mini-app/internal/models"
	"time"

	"192.168.1.75/go-pkg/errorx"
	"gorm.io/gorm"
)

type Banner struct{}

// Create 新增banner
func (Banner) Create(
	ctx context.Context,
	db *gorm.DB,
	record models.Banner,
) (id string, err error) {
	err = db.WithContext(ctx).Model(&models.Banner{}).Create(&record).Error
	return record.ID, err
}

// Update 更新banner
func (Banner) Update(
	ctx context.Context,
	db *gorm.DB,
	bannerID string,
	record models.Banner,
) error {
	return db.WithContext(ctx).Model(&models.Banner{}).
		Where("id = ?", bannerID).
		Omit("id").
		Updates(&record).Error
}

// Delete 删除banner
func (Banner) Delete(
	ctx context.Context,
	db *gorm.DB,
	bannerID string,
) error {
	rowsAffected := db.WithContext(ctx).Model(&models.Banner{}).
		Where("id = ?", bannerID).
		Delete(&models.Banner{}).RowsAffected
	if rowsAffected <= 0 {
		return errorx.New("删除失败", -1)
	}
	return nil
}

// Detail banner详情
func (Banner) Detail(
	ctx context.Context,
	db *gorm.DB,
	bannerID string,
) *models.Banner {
	var record models.Banner
	rowsAffected := db.WithContext(ctx).Model(&models.Banner{}).
		Where("id = ?", bannerID).
		Take(&record).RowsAffected
	if rowsAffected <= 0 {
		return nil
	}
	return &record
}

// List banner列表
func (Banner) List(
	ctx context.Context,
	db *gorm.DB,
	name string,
	position int, // 1-首页 2-我的
	startTime, endTime int64, // 开始时间，结束时间
	status int, // 1-待生效 2-已生效 3-已过期
	page, limit int, //分页
) (records []models.Banner, total int64) {
	tx := db.WithContext(ctx).Model(&models.Banner{})
	if name != "" {
		tx = tx.Where("name LIKE ?", "%"+name+"%")
	}
	if position > 0 {
		tx = tx.Where("position = ?", position)
	}
	if startTime > 0 && endTime > 0 {
		tx = tx.Where("start_time BETWEEN ? AND ?", startTime, endTime)
	}
	// 活动状态
	newTs := time.Now().Unix()
	switch status {
	case 1: // 进行中
		tx = tx.Where("start_time <= ? AND end_time >= ? and status = 0", newTs, newTs)
	case 2: // 未开始
		tx = tx.Where("start_time > ? AND status = 0", newTs)
	case 3: // 已结束
		tx = tx.Where("end_time < ? OR status = ?", newTs, 3)
	}
	tx.Count(&total)
	if limit > 0 {
		if limit > 2000 {
			limit = 2000
		}
		tx = tx.Limit(limit)
	}
	if page > 0 && limit > 0 {
		tx = tx.Offset((page - 1) * limit)
	}
	tx.Order(`
	CASE
		WHEN status = 3 THEN 3
		WHEN start_time <= UNIX_TIMESTAMP() AND end_time >= UNIX_TIMESTAMP() THEN 1
		WHEN start_time > UNIX_TIMESTAMP() THEN 2
		WHEN end_time < UNIX_TIMESTAMP() THEN 3
		ELSE 3
	END
	ASC,id ASC`).Find(&records)
	return
}

// Online 上架
func (Banner) Online(
	ctx context.Context,
	db *gorm.DB,
	bannerID string,
) error {
	rowsAffected := db.WithContext(ctx).Model(&models.Banner{}).
		Where("id = ?", bannerID).
		Updates(map[string]interface{}{
			"status": 0,
		}).
		RowsAffected
	if rowsAffected <= 0 {
		return errorx.New("上架失败", -1)
	}
	return nil
}

// Offline 下架
func (Banner) Offline(
	ctx context.Context,
	db *gorm.DB,
	bannerID string,
) error {
	rowsAffected := db.WithContext(ctx).Model(&models.Banner{}).
		Where("id = ?", bannerID).
		Update("status", 3).
		RowsAffected
	if rowsAffected <= 0 {
		return errorx.New(" 下架失败", -1)
	}
	return nil
}
